from flask import request, jsonify, g
from functools import wraps 
from datetime import datetime, timedelta
import jwt
import os
import base64
import returnJson

secret = os.environ.get("APP_SECRET")
def require_auth(func):  
    @wraps(func)  
    def wrapper(*args, **kwargs):  
        # 假设我们从请求中获取了身份验证信息  
        auth_header = request.headers.get('X-token')
        if not auth_header:  
            return jsonify(returnJson.error(msg=f"没有提供认证信息:X-token"))
        uid = request.args.get('uid')
        if not uid:  
            return jsonify(returnJson.error(msg=f"没有提供用户信息:uid"))
        isAuth, data= verify_jwt(auth_header)
        if isAuth:
            auid = data.get("id", "")
            if (uid == auid):
                return func(*args, **kwargs) 
            else:
                return jsonify(returnJson.error(msg=f"JWT认证失败")) 
        else:
            return jsonify(returnJson.error(msg=f"JWT认证失败"))
    return wrapper

def verify_jwt(token):
    try:
        # 提取公共部分和有效载荷
        # header, payload, signature = token.split('.')
        # 验证签名
        # jwt_token = "eyJ1eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ijk1MjcifQ.eyJpYXQiOjE1NTkyNzY5NDEuNDIwODgzNywibmFtZSI6Imxvd21hbiJ9.GyQhOJK8FKD_Gd-ggSEDPPP1Avmz3M5NDVnmfOfrEIY"
        # # decoded_data = jwt.decode(token, '695ee9563b1e1817c4fa06e7d3a117c3', algorithms=['HS256'])
        # tt = mkToken()
        # decoded_data = jwt.decode(tt, secret, algorithms=['HS256'])
        data = jwt.decode(token, base64.b64decode(secret), algorithms=['HS256'])
        return True, data
    except Exception as e:
        print(str(e))
        return False, None

def mkToken():
    payload = {
        'id':123,
        'name': '234', # type: ignore
        'exp': datetime.utcnow()+timedelta(seconds=300)
    }
    header = {
        'alg':'HS256',
        'typ':'jwt'
    }
    token = jwt.encode(payload=payload, key=secret, headers=header)
    return token

# 检测用户ID是否一致；
def checkUser(userId):
    uid = g.get("uid", None)
    if (userId == None):
        return
    if (userId != uid):
        return False
    return True